﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using Microsoft.Phone.Controls.Primitives;
using Microsoft.Devices;
using Microsoft.Phone.Shell;
using System.Diagnostics;
using Microsoft.Phone.Scheduler;

namespace Toolbox_0._0._1
{
    public partial class DateCalc : PhoneApplicationPage
    {
        private VibrateController vc;
        private bool isEventFired = false;

        //Variables for Stopwatch
        ////////////////////////////////////////////////
        private DispatcherTimer stopwatchTimer;
        private bool isStarted;
        private TimeSpan elapse;
        private TimeSpan elapseLap;
        private TimeSpan prevElapseLap;
        private int lapCount;
        private ObservableCollection<LapItem> lstLapItem;
        private Stopwatch sw;
        /////////////////////////////////////////////////

        //Variables for Timer
        /////////////////////////////////////////////////
        private DispatcherTimer timer;
        private bool isTimerStarted;
        private TimeSpan elapseTimer;
        private TimeSpan elapseCountdown;//Time set for countdown
        private Stopwatch swTimer;
        private bool is5SecAlert = false;
        private bool isSilent = false;
        private int counter=0;
        /////////////////////////////////////////////////

        public DateCalc()
        {
            InitializeComponent();
            this.hSelector.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 23, SelectedItem = 0, PrevValue = 0 };
            this.mSelector.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = 1, PrevValue = 1 };
            this.sSelector.DataSource = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = 0, PrevValue = 0 };

            hSelector.DataSource.SelectionChanged += OnHourChange;
            mSelector.DataSource.SelectionChanged += OnMinuteChange;
            sSelector.DataSource.SelectionChanged += OnSecondChange;

            //for Stopwatch
            isStarted = false;
            elapse = TimeSpan.Zero;
            elapseLap = TimeSpan.Zero;
            prevElapseLap = TimeSpan.Zero;
            lapCount = 0;
            lstLapItem = new ObservableCollection<LapItem>();
            sw = new Stopwatch();

            //for Timer
            isTimerStarted = false;
            elapseTimer = TimeSpan.Zero;
            elapseCountdown = TimeSpan.FromMinutes(1);//default 1 minutes
            swTimer = new Stopwatch();

            vc = VibrateController.Default;
        }

        private void StartStop_Click(object sender, RoutedEventArgs e)
        {
            vc.Start(TimeSpan.FromMilliseconds(100));
            //press Stop
            if (isStarted)
            {
                isStarted = false;
                stopwatchTimer.Stop();
                sw.Stop();
                btnStartStop.Content = "Start";
                btnLapReset.Content = "Reset";
                (btnStartStop.Background as SolidColorBrush).Color = Color.FromArgb(255, 0, 255, 0);


                //in case user choose to add lap when press stop
                if (lstLapItem.Count > 0)
                {
                    elapseLap = sw.Elapsed - prevElapseLap;
                    prevElapseLap = sw.Elapsed;
                    lapCount++;
                    string totalTime = lbHour.Text + lbMinute.Text + lbSecond.Text + lbMSecond.Text;

                    string lapTime = elapseLap.Hours.ToString("00") + ":"
                    + elapseLap.Minutes.ToString("00") + "'"
                    + elapseLap.Seconds.ToString("00") + "\""
                    + (elapseLap.Milliseconds / 10).ToString("00") + "";
                    elapseLap = TimeSpan.Zero;

                    //lstLapItem.Add(new LapItem("Lap " + lapCount + " <Stopped>", lapTime, totalTime));
                    lstLapItem.Insert(0, new LapItem("Lap " + lapCount + " <Stopped>", lapTime, totalTime));
                }
            }
            else //press Start
            {
                isStarted = true;
                if (stopwatchTimer == null)
                {
                    stopwatchTimer = new DispatcherTimer();
                    stopwatchTimer.Interval = TimeSpan.FromMilliseconds(1);
                    stopwatchTimer.Tick += OnStopWatchTick;
                }
                stopwatchTimer.Start();
                sw.Start();
                btnStartStop.Content = "Stop";
                btnLapReset.Content = "Lap";
                (btnStartStop.Background as SolidColorBrush).Color = Colors.Red;
            }
        }

        //An Event fired on timer tick interval for StopWatch function
        private void OnStopWatchTick(Object sender, EventArgs args)
        {
            elapse = sw.Elapsed;

            lbHour.Text = elapse.Hours.ToString("00") + ":";
            lbMinute.Text = elapse.Minutes.ToString("00") + "'";
            lbSecond.Text = elapse.Seconds.ToString("00") + "\"";
            lbMSecond.Text = (elapse.Milliseconds / 10).ToString("00");
        }

        private void LapReset_Click(object sender, RoutedEventArgs e)
        {
            vc.Start(TimeSpan.FromMilliseconds(100));
            if (isStarted)// press Lap
            {
                elapseLap = sw.Elapsed - prevElapseLap;
                prevElapseLap = sw.Elapsed;
                lapCount++;
                string totalTime = lbHour.Text + lbMinute.Text + lbSecond.Text + lbMSecond.Text;

                string lapTime = elapseLap.Hours.ToString("00") + ":"
                + elapseLap.Minutes.ToString("00") + "'"
                + elapseLap.Seconds.ToString("00") + "\""
                + (elapseLap.Milliseconds / 10).ToString("00");
                elapseLap = TimeSpan.Zero;

                //lstLapItem.Add(new LapItem("Lap " + lapCount, lapTime, totalTime));
                lstLapItem.Insert(0,new LapItem("Lap " + lapCount, lapTime, totalTime));

                lb_Laps.ItemsSource = lstLapItem;
            }
            else //press reset
            {
                sw.Reset();
                elapse = TimeSpan.Zero;
                lapCount = 0;
                elapseLap = TimeSpan.Zero;
                prevElapseLap = TimeSpan.Zero;
                lbHour.Text = "00:";
                lbMinute.Text = "00'";
                lbSecond.Text = "00\"";
                lbMSecond.Text = "00";

                if (lstLapItem != null)
                {
                    lstLapItem.Clear();
                }
            }
        }

        private void TimerStart_Click(object sender, RoutedEventArgs e)
        {
            vc.Start(TimeSpan.FromMilliseconds(100));
            //press Stop
            if (isTimerStarted)
            {
                isTimerStarted = false;
                timer.Stop();
                swTimer.Stop();
                btnStartStopTimer.Content = "Start";
                btnResetTimer.IsEnabled = true;
                (btnStartStopTimer.Background as SolidColorBrush).Color = Color.FromArgb(255, 0, 255, 0);
                hSelector.IsEnabled = true;
                mSelector.IsEnabled = true;
                sSelector.IsEnabled = true;
                spTimerNotification.Visibility = Visibility.Collapsed;
                btnSilent.Visibility = Visibility.Collapsed;
            }
            else//Press Start
            {
                isTimerStarted = true;
                if (timer == null)
                {
                    timer = new DispatcherTimer();
                    timer.Interval = TimeSpan.FromMilliseconds(100);
                    timer.Tick += OnTimerTick;
                }
                timer.Start();
                swTimer.Start();
                btnStartStopTimer.Content = "Stop";
                btnResetTimer.IsEnabled = false;
                (btnStartStopTimer.Background as SolidColorBrush).Color = Colors.Red;
                hSelector.IsEnabled = false;
                mSelector.IsEnabled = false;
                sSelector.IsEnabled = false;

                //set countdown
                int hour = (int)hSelector.DataSource.SelectedItem;
                int minute = (int)mSelector.DataSource.SelectedItem;
                int second = (int)sSelector.DataSource.SelectedItem;
                elapseCountdown = TimeSpan.FromHours(hour) + TimeSpan.FromMinutes(minute) + TimeSpan.FromSeconds(second);
                spTimerNotification.Visibility = Visibility.Visible;                
            }
        }

        private void TimerReset_Click(object sender, RoutedEventArgs e)
        {
            vc.Start(TimeSpan.FromMilliseconds(100));

            int hour = (int)hSelector.DataSource.SelectedItem;
            int minute = (int)mSelector.DataSource.SelectedItem;
            int second = (int)sSelector.DataSource.SelectedItem;

            elapseCountdown = TimeSpan.FromHours(hour) + TimeSpan.FromMinutes(minute) + TimeSpan.FromSeconds(second);
            swTimer.Reset();

            lbHourTimer.Text = hour.ToString("00") + ":";
            lbMinuteTimer.Text = minute.ToString("00") + "'";
            lbSecondTimer.Text = second.ToString("00") + "\"";
            lbMSecondTimer.Text = "00";

            lbOver.Visibility = Visibility.Collapsed;
            (spTimerNotification.Background as SolidColorBrush).Color = Color.FromArgb(255, 0, 255, 0);
            is5SecAlert = false;
            isSilent = false;

        }

        //An Event fired on timer tick interval for Timer function
        private void OnTimerTick(Object sender, EventArgs args)
        {
            elapseTimer = elapseCountdown - swTimer.Elapsed;
            //if (!isSilent && elapseTimer < TimeSpan.Zero)
            //{
            //    btnSilent.Visibility = Visibility.Visible;
            //}
            if (!isSilent && elapseTimer < TimeSpan.Zero /*&& !isTimeUp*/)
            {
                btnSilent.Visibility = Visibility.Visible;
                counter++;
                lbOver.Visibility = Visibility.Visible;
                lbTimerNotification.Text = "Timer: Time Up";
                (spTimerNotification.Background as SolidColorBrush).Color = Colors.Red;
                if (counter == 2 ||counter==1)
                {
                    spTimerNotification.Visibility = Visibility.Visible;
                }
                else
                {
                    spTimerNotification.Visibility = Visibility.Collapsed;
                }
                if (counter > 3)
                {
                    vc.Start(TimeSpan.FromMilliseconds(200));
                    counter = 0;
                }
            }
            else if (!isSilent && elapseTimer < TimeSpan.FromMinutes(1))
            {
                lbTimerNotification.Text = "Timer: Less than 1 minutes remaining";
            }
            else if (!isSilent && elapseTimer < TimeSpan.FromMinutes(5))
            {
                lbTimerNotification.Text = "Timer: Less than 5 minutes remaining";
            }

            if (!is5SecAlert && elapseTimer < TimeSpan.FromSeconds(5))
            {
                StopwatchPano.DefaultItem = StopwatchPano.Items[1];
                is5SecAlert = true;
            }


            lbHourTimer.Text = Math.Abs(elapseTimer.Hours).ToString("00") + ":";
            lbMinuteTimer.Text = Math.Abs(elapseTimer.Minutes).ToString("00") + "'";
            lbSecondTimer.Text = Math.Abs(elapseTimer.Seconds).ToString("00") + "\"";
            lbMSecondTimer.Text = Math.Abs(elapseTimer.Milliseconds / 10).ToString("00");

        }

        private bool isChangeTimer()
        {
            int hour = (int)hSelector.DataSource.SelectedItem;
            int minute = (int)mSelector.DataSource.SelectedItem;
            int second = (int)sSelector.DataSource.SelectedItem;
            elapseCountdown = TimeSpan.FromHours(hour) + TimeSpan.FromMinutes(minute) + TimeSpan.FromSeconds(second);
            if (elapseCountdown <= TimeSpan.FromSeconds(2))
            {
                MessageBox.Show("Countdown Time should be greater than 2 seconds", "Warning", MessageBoxButton.OK);
                return false;
            }
            if (swTimer.Elapsed > TimeSpan.Zero)
            {
                if (MessageBox.Show("Changing Countdown Time will reset Timer. Are you sure?", "Confirmation", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
                {
                    swTimer.Reset();

                    lbHourTimer.Text = hour.ToString("00") + ":";
                    lbMinuteTimer.Text = minute.ToString("00") + "'";
                    lbSecondTimer.Text = second.ToString("00") + "\"";
                    lbMSecondTimer.Text = "00";

                    lbOver.Visibility = Visibility.Collapsed;
                    is5SecAlert = false;
                    isSilent = false;

                    return true;
                }
                else
                {
                    return false;
                }
            }

            swTimer.Reset();

            lbHourTimer.Text = hour.ToString("00") + ":";
            lbMinuteTimer.Text = minute.ToString("00") + "'";
            lbSecondTimer.Text = second.ToString("00") + "\"";
            lbMSecondTimer.Text = "00";

            lbOver.Visibility = Visibility.Collapsed;
            is5SecAlert = false;
            isSilent = false;

            return true;
        }

        //An event fired when selector changes
        private void OnHourChange(object oldSelectedItem, object newSelectedItem)
        {
            if (!isEventFired)
            {
                if (!isChangeTimer())
                {
                    isEventFired = true;
                    IntLoopingDataSource tmp = new IntLoopingDataSource() { MinValue = 0, MaxValue = 23, SelectedItem = (hSelector.DataSource as LoopingDataSourceBase).PrevValue, PrevValue = (hSelector.DataSource as LoopingDataSourceBase).PrevValue };
                    tmp.SelectionChanged += OnHourChange;
                    hSelector.DataSource = tmp;
                    isEventFired = false;
                }
            }
        }
        private void OnMinuteChange(object oldSelectedItem, object newSelectedItem)
        {
            if (!isEventFired)
            {
                if (!isChangeTimer())
                {
                    isEventFired = true;
                    IntLoopingDataSource tmp = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = (mSelector.DataSource as LoopingDataSourceBase).PrevValue, PrevValue = (mSelector.DataSource as LoopingDataSourceBase).PrevValue };
                    tmp.SelectionChanged += OnMinuteChange;
                    mSelector.DataSource = tmp;
                    isEventFired = false;
                }
            }
        }
        private void OnSecondChange(object oldSelectedItem, object newSelectedItem)
        {
            if (!isEventFired)
            {
                if (!isChangeTimer())
                {
                    isEventFired = true;
                    IntLoopingDataSource tmp = new IntLoopingDataSource() { MinValue = 0, MaxValue = 59, SelectedItem = (sSelector.DataSource as LoopingDataSourceBase).PrevValue, PrevValue = (sSelector.DataSource as LoopingDataSourceBase).PrevValue };
                    tmp.SelectionChanged += OnSecondChange;
                    sSelector.DataSource = tmp;
                    isEventFired = false;
                }
            }
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {

            PhoneApplicationService.Current.State["PanoramaSelectedItem"] = StopwatchPano.SelectedIndex;
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {

            if (PhoneApplicationService.Current.State.ContainsKey("PanoramaSelectedItem"))
            {

                var selIndex = (int)PhoneApplicationService.Current.State["PanoramaSelectedItem"];

                StopwatchPano.DefaultItem = StopwatchPano.Items[selIndex];

            }

        }

        private void Silent_Click(object sender, RoutedEventArgs e)
        {
            isSilent = true;
            btnSilent.Visibility = Visibility.Collapsed;
            spTimerNotification.Visibility = Visibility.Visible;
        }

    }
}